package com.example.liyun.joy.serviceutils;

import android.os.Environment;
import android.util.Log;

import com.example.liyun.joy.MainActivity;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * retrofit请求，生成接口实例的管理类
 */
public class RetrofitServiceManager {
    //创建retrofit对象
    public Retrofit mRetrofit;

    /**
     * 在构造方法中实现初始化，并配置参数
     */
    public RetrofitServiceManager(){
        //Okhttp缓存路径
        File httpCacheDirectory=new File(MainActivity.getmContext().getCacheDir(),"cache_responses");

        httpCacheDirectory.mkdirs();
        //缓存大小
        int cacheSize=10*1024*1024;
        Cache cache=new Cache(httpCacheDirectory,cacheSize);

        //创建OkhttpClient，以此方式去发送网络请求
        OkHttpClient.Builder builder=new OkHttpClient.Builder();
        builder.callTimeout(ApiConfig.DEFAULT_TIME_OUT,TimeUnit.SECONDS);//设置连接超时，TimeUnit.SECONDS：代表时间数值的单位（h，min,s,ms等）
        builder.readTimeout(ApiConfig.DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//设置读取超时
        builder.cache(cache);//配置缓存

        Interceptor cacheInterceptor=new Interceptor() {
            /*//通过CacheControl控制缓存数据
            CacheControl.Builder cacheBuilder=new CacheControl.Builder()
                    .maxAge(5,TimeUnit.SECONDS)//控制缓存的最大生命时间，有网缓存最大生命时间
                    .maxStale(1,TimeUnit.DAYS);//控制缓存的过时时间，没网缓存最大生命时间
            CacheControl cacheControl=cacheBuilder.build();*/
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request=chain.request();
                /**
                 * 必须得写，不然断网状态下，退出应用，或者等待一分钟后，就获取不到缓存
                 */
                if (!NetWorkUtils.isNetworkAvailable(MainActivity.getmContext())){//当没网时强制从缓存中读取
                    request=request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }
                Response oldResponse=chain.proceed(request);
                Response cacheResponse;
                if (NetWorkUtils.isNetworkAvailable(MainActivity.getmContext())){
                    int maxAge=60;//有网失效1分钟
                    cacheResponse=oldResponse.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control","public ,max-age="+maxAge)
                            .build();
                }else {
                    int maxStale=60*60*24;//没网失效24小时
                    cacheResponse=oldResponse.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control","public, only-if-cached, max-stale="+maxStale)
                            .build();
                }
                return cacheResponse;
            }
        };

        //添加缓存拦截器
        //HttpInterceptor cacheInterceptor=new HttpInterceptor.Builder().build();
        builder.addInterceptor(cacheInterceptor);
        //builder.addNetworkInterceptor(cacheInterceptor);

        /*//还可以给Okhttp添加公共参数拦截器，和请求头拦截器，需要实现implements Interceptor
        HttpInterceptor paramsInterceptor;
        if(typeName.equals("joke")){//判断是哪个模块请求数据
            paramsInterceptor=new HttpInterceptor.Builder()
                    .addUrlParams("key",ApiConfig.JOKEKEY)
                    .build();
        }else {
            paramsInterceptor=new HttpInterceptor.Builder()
                    .addUrlParams("key",ApiConfig.NEWSKEY)
                    .build();
        }
        //向OkhttpClient添加拦截器
        builder.addInterceptor(paramsInterceptor);*/

        //初始化retrofit
        mRetrofit=new Retrofit.Builder()
                .baseUrl(ApiConfig.BASE_URL)
                .client(builder.build())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加Rxjava订阅处理返回的结果
                .addConverterFactory(GsonConverterFactory.create())//添加自带的json解析器
                .build();
    }

    /**
     * 创建一个静态类，用于将RetrofitServiceManager管理类设置为常量，这样就不用每次调用时都需要去new
     */
    public static class SigleHolder{
        public static final RetrofitServiceManager INSTANCE=new RetrofitServiceManager();
    }

    /**
     * 创建被一个方法，用于提供外部类获取RetrofitServiceManager 对象
     * @return
     */
    public static RetrofitServiceManager getInstance(){
        return SigleHolder.INSTANCE;
    }

    /**
     * 创建一个泛型接口对象，此时还不知道传入和返回的数据时什么数据，所以这里使用泛型适配所有类型的对象
     * 获取对应的service接口对象
     * @param service 传入的数据类型
     * @param <T> 返回数据类型
     * @return
     */
    public <T> T creat(Class<T> service){
        return mRetrofit.create(service);
    }
}
